<?php
/***********************************************************************
 * @package     IvanEngine
 * @subpackage  Core
 * @author      Ivan <ivanzx@msn.com>
 * @created     2010-06-16
 ***********************************************************************/
if(defined("IVANENGINE_CORE_IO_DATASTREAM"))
    die("Redefinition macro in :".__FILE__."(".__LINE__.")");
define("IVANENGINE_CORE_IO_DATASTREAM", true);

require_once (dirname(__FILE__).'/../Common.php');
require_once (dirname(__FILE__).'/Stream.php');

class CDataStream extends CObject implements IStream
{
    protected   
        $m_position = 0,
        $m_data     = null;
    
    function __construct($data)
    {
        parent::__construct();
        $this->Open($data);
    }

    function __destruct()
    {
        $this->Close();
        parent::__destruct();
    }
    
    public function Open($data, $mode = 'r')
    {
        $this->m_data = $data;
    }
    
    public function Close()
    {
        unset($this->m_data);
    }

    public function Read($length = 1)
    {
        $returnValue = substr($this->m_data, $this->m_position, $length);
        $this->m_position += $length;
        return $returnValue;
    }
    
    public function ReadAll()
    {
        $tmpPos = $this->m_pos;
        $this->m_position    = 0;
        $result = $this->Read($this->Size());
        $this->m_position    = $tmpPos;
    }

    public function Write($data, $length = null)
    {
        if ($length !== null) {
            $this->m_data .= substr($data, 0, $length);
        } else {
            $this->m_data .= $data;
        }

        $this->m_position = $this->Size();
    }
    
    public function WriteAll($data, $length = null)
    {
        $this->m_data   = '';
        $this->Write($data, $length);
    }
    
    public function Seek($offset, $whence=SEEK_SET)
    {
        switch ($whence) 
        {
            case SEEK_SET:
                $this->m_position = $offset;
                break;

            case SEEK_CUR:
                $this->m_position += $offset;
                break;

            case SEEK_END:
                $this->m_position = $this->Size();
                $this->m_position += $offset;
                break;

            default:
                break;
        }
    }

    public function Tell()
    {
        return $this->m_position;
    }

    public function Flush()
    {
        return true;
    }

    public function Lock($lockType, $nonBlockinLock = false)
    {
        return true;
    }

    public function Unlock()
    {
        
    }
    
    public function Size()
    {
        return  strlen($this->m_data);
    }
}
?>
